<!-- Created by henian.xu on 2018/8/31. -->

<template>
    <el-select
        ref="select"
        class="remote-select"
        popper-class="remote-select-popper"
        filterable
        :filter-method="filterMethod"
        @visible-change="onVisibleChange"
        :allow-create="allowCreate"
        :default-first-option="defaultFirstOption||allowCreate"
        v-model="model"
        v-loading="addLoading"
    >
        <el-option
            v-for="(item) in dataList"
            :key="item[props.id]"
            :label="item[props.name]"
            :value="item[props.id]"
            :disabled="item.__disabled"
        />
        <template v-if="pagination.totalRows">
            <div
                v-if="isComplete"
                class="el-select-dropdown__empty" >没有更多了</div>
            <div
                v-else
                class="el-select-dropdown__empty">
                <i class="el-icon-loading"/>正在加载...
            </div>
        </template>
    </el-select>
</template>
<script>
import hijackScrollbar from './hijackScrollbar';
export default {
    name: 'RemoteSelect',
    mixins: [hijackScrollbar],
    data() {
        return {
            dataList: [],
            pagination: {},
            isPagination: false,
            keyword: '',
            addLoading: false,
            oldValue: null,
        };
    },

    props: {
        value: {
            type: [Number, String],
            required: true,
        },
        remote: {
            type: String,
            required: true,
        },
        remoteParams: {
            type: Object,
            default() {
                return {};
            },
        },
        allowCreate: {
            type: Boolean,
            default: false,
        },
        allowCreateMethod: {
            type: Function,
            default: null,
        },
        defaultFirstOption: {
            type: Boolean,
            default: false,
        },
        extendReload: {
            type: Boolean,
            default: false,
        },
        initData: {
            type: Array,
            default() {
                return [];
            },
        },
        // 排除不显示的的 id, 如果包含 value.id 依然可选
        exclude: {
            type: Array,
            default() {
                return [];
            },
        },
        props: {
            type: Object,
            default() {
                return {
                    id: 'id',
                    name: 'name',
                };
            },
        },
    },
    computed: {
        model: {
            get() {
                return this.value;
            },
            set(val) {
                // console.log(val);
                const { keyword, allowCreate, allowCreateMethod } = this;
                if (allowCreate && keyword === val && allowCreateMethod) {
                    // console.log('is new Create');
                    this.addLoading = true;
                    allowCreateMethod(val)
                        .then(json => {
                            const res = json.data;
                            console.log(res.data);
                            this.dataList.push({
                                [this.props.id]: res.data,
                                [this.props.name]: val,
                            });
                            this.$nextTick(() => {
                                this.addLoading = false;
                                this.$emit('input', res.data);
                                this.oldValue = res.data;
                                this.$emit('change', res.data);
                            });
                        })
                        .catch(() => {
                            this.addLoading = false;
                            this.$emit('input', this.oldValue);
                        });
                } else {
                    this.$emit('input', val);
                    this.oldValue = val;
                    this.$emit('change', val);
                }
            },
        },
        dataMap() {
            return this.dataList.reduce((prev, curr, index) => {
                curr.__index = index;
                prev[curr[this.props.id]] = curr;
                return prev;
            }, {});
        },
        excludeMap() {
            const id = this.value.id;
            return this.exclude.reduce((prev, curr) => {
                prev[curr] = curr !== id;
                return prev;
            }, {});
        },
        $$select() {
            return this.$refs.select;
        },
        filterMethod() {
            return this.isPagination ? this.onFilter : null;
        },
    },
    methods: {
        getDataList() {
            return this.$http
                .get(this.remote, {
                    ...this.remoteParams,
                    keyword: this.keyword,
                    currentPage: this.pagination.currentPage ? this.pagination.currentPage + 1 : 1,
                    _isRepeat: true,
                })
                .then(json => {
                    const res = json.data;
                    res.data.reverse().forEach((item, index) => {
                        item.__disabled = !!this.excludeMap[item[this.props.id]];
                        const mapItem = this.dataMap[item[this.props.id]];
                        if (mapItem) {
                            this.dataList.splice(mapItem.__index, 1, item);
                            res.data.splice(index, 1);
                        }
                    });
                    res.data.reverse();
                    this.dataList = this.dataList.concat(res.data);
                    return Promise.resolve(json);
                });
        },
        onLoad() {
            return this.getDataList().then(json => {
                const res = json.data;
                this.pagination = res.pagination || {};
                this.isPagination = !!res.pagination;
                const { currentPage, totalRows, totalPages } = this.pagination;
                let loadStatus = '';
                /*if (currentPage === 1) {
                    // 第一次
                    console.log('first');
                }*/
                if (!totalRows || currentPage === totalPages) {
                    // 完成
                    loadStatus = 'complete';
                } else {
                    // 继续
                    loadStatus = 'loaded';
                }
                return Promise.resolve(loadStatus);
            });
        },
        onFilter(keyword) {
            this.keyword = keyword || '';
            this.pagination = {};
            this.dataList = [];
            this.loadStatus = '';
            this.isLoading = false;
            this.$nextTick(() => {
                this.onScroll();
            });
        },
        onVisibleChange(val) {
            if (!this.extendReload || !val) return;
            this.onFilter();
        },
        getData(id) {
            return this.dataMap[id];
        },
    },
    created() {
        this.dataList = this.dataList.concat(this.initData);
    },
    mounted() {
        this.onScroll();
    },
};
</script>

<style lang="scss">
.remote-select-popper {
}
</style>
